package agent;

//import repast.symphony.annotate.AgentAnnot;
import java.awt.geom.Point2D;
import java.io.*;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.lang.Object;
import java.util.Vector;
import java.util.Collections;

import repast.simphony.context.Context;
import repast.simphony.engine.environment.RunEnvironment;
import repast.simphony.engine.schedule.ScheduledMethod;
import repast.simphony.parameter.Parameters;
import repast.simphony.random.RandomHelper;
import repast.simphony.space.continuous.ContinuousSpace;
import repast.simphony.space.continuous.NdPoint;
import repast.simphony.space.grid.Grid;
import repast.simphony.space.grid.GridPoint;
import repast.simphony.util.ContextUtils;
import repast.simphony.engine.schedule.ISchedule;
import javax.swing.AbstractAction;
import saf.core.ui.actions.AbstractSAFAction;
import repast.simphony.engine.schedule.Schedule;
import repast.simphony.ui.action.StopRun;

import agent.lichenRaster;
import agent.map_affich;

//@AgentAnnot(displayName = "Agent")
public class Agent {
	//private double energy;       // The energy level of the agent
	private double heading;      // The heading in degrees of the agent
	private double TA;
	//private Point2D.Double position;
	public String name;
	public String[][] localisation;
	public double[][] localisation2;
	private int ID;
	public int iteration;
	public static int iteration_gen = 0;
	public static int hour = 0;
	public short debut;
	public double xreal, yreal;
	public int count;
	public static int nbL=0;
	public static int nbLDie=0;
	public String date_init;
	public double X_init,Y_init;
	public int step_ok=0;
	public static Vector Caribou_indices=new Vector();
	public static Vector Orignal_indices=new Vector();
	public static int nb_years=0;
	public static int nb_dead_car=0;
	public static int nb_dead_ori=0;
	public static int nb_dead_car_pred=0;
	public static int nb_dead_ori_pred=0;
	public int age;
	public static String carte;
	//public static ArrayList<Agent> DeadCaribous;
	//public static ArrayList<Agent> DeadMooses;
	
	public static void setup()
	{
		nbL=0; //NON UTILISE?? KL
		nbLDie=0; //NON UTILISE?? KL
		hour = 0;
		iteration_gen = 0;
		Caribou_indices=new Vector();
		Orignal_indices=new Vector();
		nb_years=0;
		nb_dead_car=0;
		nb_dead_ori=0;
	}
	
	
//	@ScheduledMethod(start=1, interval=1, priority=1, pick=1)
//	public void new_year()
//	{
//		ISchedule s = RunEnvironment.getInstance().getCurrentSchedule();
//		// afficher le tick en cours
//		System.out.println("Nombre de ticks: "+s.getTickCount());
//		if (nb_years == 0){
//			System.out.println("annee completee: " + nb_years + "-- carte utilisee: "+ GIS.carteDepart);	
//		}
//		else {
//			System.out.println("annee completee: " + nb_years + "-- carte utilisee: "+ carte );	
//		}
//		
//		
//		// cas du premier tick
//		if (s.getTickCount() == 1){
//			nb_years = 0;
//			carte = CST.Path_ressource_maps + "simu2000.txt";
//			GIS.setup2(carte);
//			System.out.println("Annee completee: " + nb_years + "-- Nombre de ticks: "+s.getTickCount());
//			// recrutement
//			this.recrute();
//		}
//		// pour le cas d'un changement d'annee
//		else if (s.getTickCount() > 1 && s.getTickCount() % 558 == 1){	
//			// incrémenter le nombre d'annees
//			nb_years ++;
//			System.out.println("Annee completee: " + nb_years);
//			// recrutement
//			this.recrute();
//			// vérifier si on change de carte
//			if (this.changeMap(nb_years)){
//				// changer le chemin d'acces de la carte
//				carte = this.newMapPath(nb_years);
//				System.out.println("nb_years: " + nb_years + ", donc chargement de: "+ carte );	
//				// setup de GIS
//				GIS.setup2(carte);
//				// relocaliser les caribous si nécessaire
//				this.relocateCaribou();
//			}
//			// gerer la population
//			this.managePopulations();			
//			// sauver le nombre de proies predatees
//			save_numdeadpred();
//			// reinitialiser le nombre de proies a zero
//			nb_dead_car_pred=0;
//			nb_dead_ori_pred=0;			
//		}
//	} // fin de new_year()		
//	
//	private void managePopulations(){
//		Context context = ContextUtils.getContext(this);
//		ContinuousSpace space = (ContinuousSpace) context.getProjection("Continuous Space");
//		Grid patch = (Grid) context.getProjection("Simple Grid");
//		Grid patchDisplay = (Grid) context.getProjection("Display Grid");
//		
//		//ajout pour maintenir la population constante
//		Parameters p = RunEnvironment.getInstance().getParameters();
//		int nb_car_ajoute=(Integer)p.getValue("initialnumberofcaribou")-PPContextCreator.allCaribous.size();
//		int nb_ori_ajoute=(Integer)p.getValue("initialnumberofmoose")-PPContextCreator.allMooses.size();
//			
//		for(int i=0;i<nb_car_ajoute;i++)
//		{
//			Caribou caribou = new Caribou();     // create a new caribou
//			context.add(caribou);                 // add a new caribou to the root context
//
//			double x_localisation = Math.random()*GIS.landUseMap.width;
//			double y_localisation = Math.random()*GIS.landUseMap.height;
//					
//			while(GIS.landUseMap.matrix[(int)x_localisation][(int)y_localisation]!=(byte)11)
//			{
//				x_localisation = Math.random()*GIS.landUseMap.width;
//				y_localisation = Math.random()*GIS.landUseMap.height;
//			}
//
//			space.moveTo(caribou,x_localisation,y_localisation);
//			patch.moveTo(caribou,(int)x_localisation,(int)y_localisation);
//			patchDisplay.moveTo(caribou,Math.min((int)x_localisation/CST.div_affich,(int)GIS.landUseMap.width/CST.div_affich-1),Math.min((int)y_localisation/CST.div_affich,(int)GIS.landUseMap.height/CST.div_affich-1));
//					
//			caribou.xreal = x_localisation*25+GIS.landUseMap.getOriginX();
//			caribou.yreal = y_localisation*25+GIS.landUseMap.getOriginY();
//				
//		}
//			
//		for(int i=0;i<nb_ori_ajoute;i++)
//		{
//			Moose moose = new Moose();     // create a new moose
//			context.add(moose);  
//	
//			double x_localisation = Math.random()*GIS.landUseMap.width;
//			double y_localisation = Math.random()*GIS.landUseMap.height;
//				
//			while(!(GIS.landUseMap.matrix[(int)x_localisation][(int)y_localisation]==(byte)12 || GIS.landUseMap.matrix[(int)x_localisation][(int)y_localisation]==(byte)71 || GIS.landUseMap.matrix[(int)x_localisation][(int)y_localisation]==(byte)72))
//			{
//				x_localisation = Math.random()*GIS.landUseMap.width;
//				y_localisation = Math.random()*GIS.landUseMap.height;
//			}
//					
//			space.moveTo(moose,x_localisation,y_localisation);
//			patch.moveTo(moose,(int)x_localisation,(int)y_localisation);
//			patchDisplay.moveTo(moose,Math.min((int)x_localisation/CST.div_affich,(int)GIS.landUseMap.width/CST.div_affich-1),Math.min((int)y_localisation/CST.div_affich,(int)GIS.landUseMap.height/CST.div_affich-1));
//					
//			moose.xreal = x_localisation*25+GIS.landUseMap.getOriginX();
//			moose.yreal = y_localisation*25+GIS.landUseMap.getOriginY();					
//			
//		}		
//	}
//	
//	private void relocateCaribou(){
//		Context context = ContextUtils.getContext(this);
//		ContinuousSpace space = (ContinuousSpace) context.getProjection("Continuous Space");
//		//r�initialiser la position si dans une coupe (on tire 8 rayons, et quand on sort de la coupe pour un des rayons, on relocalise)
//		for(int i=0;i<PPContextCreator.allCaribous.size();i++)
//		{
//			NdPoint pointC = space.getLocation(PPContextCreator.allCaribous.get(i));
//			if (GIS.landUseMap.matrix[(int)pointC.getX()][(int)pointC.getY()]==13 || GIS.landUseMap.matrix[(int)pointC.getX()][(int)pointC.getY()]==14)
//			{
//				int temp=0;
//				int dist=1;
//				int[] count_no_cut={0,0,0,0,0,0,0,0};
//				int[] xdir={1,1,0,-1,-1,-1,0,1};
//				int[] ydir={0,1,1,1,0,-1,-1,-1};
//				while (temp==0)
//				{
//					for (int j=0;j<8;j++)
//					{
//						if((int)pointC.getX()+(int)(dist*xdir[j])>=0 && (int)pointC.getX()+(int)(dist*xdir[j])<GIS.landUseMap.getSizeX() && (int)pointC.getY()+(int)(dist*ydir[j])>=0 && (int)pointC.getY()+(int)(dist*ydir[j])<GIS.landUseMap.getSizeY())
//						{ //verifie qu'on ne sort pas de la carte
//							if (GIS.landUseMap.matrix[(int)pointC.getX()+(int)(dist*xdir[j])][(int)pointC.getY()+(int)(dist*ydir[j])]!=13 && GIS.landUseMap.matrix[(int)pointC.getX()+(int)(dist*xdir[j])][(int)pointC.getY()+(int)(dist*ydir[j])]!=14)
//							{	//dans un coupe (recente ou en r�g�n�ration) ?
//								count_no_cut[j]++;
//								if (count_no_cut[j]>=10)
//								{ //v�rifie qu'on est vraiment sorti de la coupe (250m)
//									space.moveByDisplacement(PPContextCreator.allCaribous.get(i),dist*xdir[j],dist*ydir[j],0); //relocalise
//									temp=1;
//								}
//							}
//							else
//							{
//								count_no_cut[j]=0;	//r�initialise si on retombe dans une coupe
//							}
//						}
//					}
//					dist++;
//				}
//			}
//		}
//	}
//	
//	private void recrute(){
//		//Recrutement	
//		ArrayList<Agent> DeadCaribous=new ArrayList<Agent>(0);
//		ArrayList<Agent> DeadMooses=new ArrayList<Agent>(0);
//		Context context = ContextUtils.getContext(this);
//		ContinuousSpace space = (ContinuousSpace) context.getProjection("Continuous Space");
//		Grid patch = (Grid) context.getProjection("Simple Grid");
//		Grid patchDisplay = (Grid) context.getProjection("Display Grid");
//	}
//
//	/**
//	 * Set map path for a given simulation year
//	 * @param simuYear year in simulation
//	 * @return map path
//	 */
//	private String newMapPath(int simuYear){
//		String basePath = CST.Path_ressource_maps + "simu";
//		String ext = ".txt";
//		if (simuYear > 0 && simuYear <= 5){
//			return basePath + 2000 + ext;
//		}
//		else if (simuYear > 5 && simuYear <= 10){
//			return basePath + 2005 + ext;
//		}
//		else if (simuYear > 10 && simuYear <= 15){
//			return basePath + 2010 + ext;
//		}
//		else if (simuYear > 15 && simuYear <= 20){
//			return basePath + 2015 + ext;
//		}
//		else if (simuYear > 20 && simuYear <= 25){
//			return basePath + 2020 + ext;
//		}
//		else if (simuYear > 25 && simuYear <= 30){
//			return basePath + 2025 + ext;
//		}
//		else if (simuYear > 30 && simuYear <= 35){
//			return basePath + 2030 + ext;
//		}
//		else if (simuYear > 35 && simuYear <= 40){
//			return basePath + 2035 + ext;
//		}
//		else if (simuYear > 40 && simuYear <= 45){
//			return basePath + 2040 + ext;
//		}
//		else if (simuYear > 45 && simuYear <= 50){
//			return basePath + 2045 + ext;
//		}
//		else if (simuYear > 50 && simuYear <= 55){
//			return basePath + 2050 + ext;
//		}
//		else if (simuYear > 55 && simuYear <= 60){
//			return basePath + 2055 + ext;
//		}
//		else if (simuYear > 60 && simuYear <= 65){
//			return basePath + 2060 + ext;
//		}
//		else if (simuYear > 65 && simuYear <= 70){
//			return basePath + 2065 + ext;
//		}
//		else if (simuYear > 70 && simuYear <= 75){
//			return basePath + 2070 + ext;
//		}
//		else if (simuYear > 75 && simuYear <= 80){
//			return basePath + 2075 + ext;
//		}
//		else if (simuYear > 80 && simuYear <= 85){
//			return basePath + 2080 + ext;
//		}
//		else if (simuYear > 85 && simuYear <= 90){
//			return basePath + 2085 + ext;
//		}
//		else if (simuYear > 90 && simuYear <= 95){
//			return basePath + 2090 + ext;
//		}
//		else if (simuYear > 95 && simuYear <= 100){
//			return basePath + 2095 + ext;
//		}
//		else if (simuYear > 100 && simuYear <= 105){
//			return basePath + 2100 + ext;
//		}
//		else if (simuYear > 105 && simuYear <= 110){
//			return basePath + 2105 + ext;
//		}
//		else if (simuYear > 110 && simuYear <= 115){
//			return basePath + 2110 + ext;
//		}
//		else if (simuYear > 115 && simuYear <= 120){
//			return basePath + 2115 + ext;
//		}
//		else if (simuYear > 120 && simuYear <= 125){
//			return basePath + 2120 + ext;
//		}
//		else if (simuYear > 125 && simuYear <= 130){
//			return basePath + 2125 + ext;
//		}
//		else if (simuYear > 130 && simuYear <= 135){
//			return basePath + 2130 + ext;
//		}
//		else if (simuYear > 135 && simuYear <= 140){
//			return basePath + 2135 + ext;
//		}
//		else if (simuYear > 140 && simuYear <= 145){
//			return basePath + 2140 + ext;
//		}
//		else if (simuYear > 145 && simuYear <= 150){
//			return basePath + 2145 + ext;
//		}
//		else if (simuYear > 150 && simuYear <= 155){
//			return basePath + 2150 + ext;
//		}
//		else {
//			throw new IllegalArgumentException("ERROR: wrong simulation year passed in parameter:  " + simuYear);
//		}
//	}
//	
//	/**
//	 * Determine if the map needs to be change or not
//	 * @param simuYear year in simulation
//	 * @return true if the map needs
//	 */
//	private boolean changeMap(int simuYear){
//		switch (simuYear){
//			case 5:
//				return true;
//			case 10:
//				return true;
//			case 15:
//				return true;
//			case 20:
//				return true;
//			case 25:
//				return true;
//			case 30:
//				return true;
//			case 35:
//				return true;
//			case 40:
//				return true;
//			case 45:
//				return true;
//			case 50:
//				return true;
//			case 55:
//				return true;
//			case 60:
//				return true;
//			case 65:
//				return true;
//			case 70:
//				return true;
//			case 75:
//				return true;
//			case 80:
//				return true;
//			case 85:
//				return true;
//			case 90:
//				return true;
//			case 95:
//				return true;
//			case 100:
//				return true;
//			case 105:
//				return true;
//			case 110:
//				return true;
//			case 115:
//				return true;
//			case 120:
//				return true;
//			case 125:
//				return true;
//			case 130:
//				return true;
//			case 135:
//				return true;
//			case 140:
//				return true;
//			case 145:
//				return true;
//			case 150:
//				return true;
//			default:
//				return false;
//		}
//	}
	
	@ScheduledMethod(start=1, interval=1, priority=1, pick=1)
	public void new_year()
	
	/*
	 * Pseudo-protocole pour garder le nombre de caribous constant à chaque année
	 * 1) Voir la taille de l'array list PPContextCreator.allCaribous
	 * 2) créer une constante, ex int NUM_CARIBOUS = 700 ou y accéder via une constante static PPContextCreator
	 * 3) En fonction de la différence, on ajoute/retire des caribous à l'array-List PPContextCreator.allCaribous
	 * 3a) si on doit retirer, on choisi n nombres aléatoires entre 0 et le taille-1 et on fait un remove 
	 * pour ces indices dans l'array list PPContextCreator.allCaribous
	 * 3b) Si on doit en ajouter, on créer des nouveaux caribous conformément aux règles établies (à voir de quelles
	 * règles il s'agit) et on fait tout simplement un add de ces nouveaux agents dans l'array list PPContextCreator.allCaribous
	 * 
	 */
	
	{
	ISchedule s = RunEnvironment.getInstance().getCurrentSchedule();
	System.out.println("Nombre de ticks: "+s.getTickCount());
	
	
	
	//debut ici
	if(s.getTickCount()%558==1) //ajout d'une année
	{
		
	System.out.println("nb ticks % 558 == 1, car nb ticks : "+s.getTickCount());	
	
		if(s.getTickCount()>1)
		{
			save_numdeadpred();
		}
			
		nb_dead_car_pred=0;
		nb_dead_ori_pred=0;
		
		if(nb_years == 0)
		{
			System.out.println("nb_years dans if(nb_years == 0) AVANT : " + nb_years);
			nb_years = 1;
			System.out.println("nb_years dans if(nb_years == 0) APRES : " + nb_years);
		}
		//System.out.println("si tick%558 = 1   tick:" + s.getTickCount());
		
		else	
		{
			System.out.println("nb_years :" + nb_years); 
			nb_years++;
			System.out.println("nb_years mis a jour:" + nb_years); 
		}
			

				
			//Recrutement	
			ArrayList<Agent> DeadCaribous=new ArrayList<Agent>(0);
			ArrayList<Agent> DeadMooses=new ArrayList<Agent>(0);
			Context context = ContextUtils.getContext(this);
			ContinuousSpace space = (ContinuousSpace) context.getProjection("Continuous Space");
			Grid patch = (Grid) context.getProjection("Simple Grid");
			Grid patchDisplay = (Grid) context.getProjection("Display Grid");
			

			
/*			//tuer le nb d'individus tu�s dans l'ann�e *3, autour des loups
			ArrayList<Integer> car_num = new ArrayList<Integer>();
			for(int i=0;i<PPContextCreator.allCaribous.size();i++)
			{
				car_num.add(i);
			}
			Collections.shuffle(car_num);
			
			ArrayList<Integer> ori_num = new ArrayList<Integer>();
			for(int i=0;i<PPContextCreator.allMooses.size();i++)
			{
				ori_num.add(i);
			}
			Collections.shuffle(ori_num);
			
			System.out.println("nb_dead_car = "+nb_dead_car);
			int nb_dead_car_count=0;
			ArrayList<Integer> car_num_enleve = new ArrayList<Integer>();
			for(int i=0;i<car_num.size();i++)
			{
				if (nb_dead_car_count<3*nb_dead_car) // valeur 3 a modifier car on enleve peut être un peu trop d'individus test 2.5
				{
					NdPoint pointC = space.getLocation(PPContextCreator.allCaribous.get(car_num.get(i)));
					int pred=0;
					for(int j=0;j<PPContextCreator.allWolves.size();j++)
					{
						NdPoint pointL = space.getLocation(PPContextCreator.allWolves.get(j));
						if (space.getDistance(pointL, pointC)<=(2*11500/25) && pred==0)
						{	//cf Mech(1994) *2
							DeadCaribous.add(PPContextCreator.allCaribous.get(car_num.get(i)));
							//car_num.remove(i);
							car_num_enleve.add(i);
							pred=1;
							nb_dead_car_count++;
						}
					}
				}
			}
			for(int i=0;i<car_num_enleve.size();i++)
			{
				car_num.remove(i);
			}
//			if (nb_dead_car_count<3*nb_dead_car)
//			{
//				for(int i=0;i<car_num.size();i++)
//				{
//					if(nb_dead_car_count<=3*nb_dead_car)
//					{
//						DeadCaribous.add(PPContextCreator.allCaribous.get(car_num.get(i)));
//						nb_dead_car_count++;
//					}
//				}
//			}
			
			System.out.println("nb_dead_ori = "+nb_dead_ori);
			int nb_dead_ori_count=0;
			ArrayList<Integer> ori_num_enleve = new ArrayList<Integer>();
			for(int i=0;i<ori_num.size();i++)
			{
				if (nb_dead_ori_count<3*nb_dead_ori) // valeur 3 a modifier car on enleve peut être un peu trop d'individus test 2.5
				{
					NdPoint pointC = space.getLocation(PPContextCreator.allMooses.get(ori_num.get(i)));
					int pred=0;
					for(int j=0;j<PPContextCreator.allWolves.size();j++)
					{
						NdPoint pointL = space.getLocation(PPContextCreator.allWolves.get(j));
						if (space.getDistance(pointL, pointC)<=(2*11500/25) && pred==0)
						{	//cf Mech(1994) *2
							DeadMooses.add(PPContextCreator.allMooses.get(ori_num.get(i)));
							//ori_num.remove(i);
							ori_num_enleve.add(i);
							pred=1;
							nb_dead_ori_count++;
						}
					}
				}
			}
			for(int i=0;i<ori_num_enleve.size();i++)
			{
				ori_num.remove(i);
			}
//			if (nb_dead_ori_count<3*nb_dead_ori)
//			{
//				for(int i=0;i<ori_num.size();i++)
//				{
//					if(nb_dead_ori_count<=3*nb_dead_ori)
//					{
//						DeadMooses.add(PPContextCreator.allMooses.get(ori_num.get(i)));
//						nb_dead_ori_count++;
//					}
//				}
//			}
			
			System.out.print("");
			
			for(int i=0;i<DeadCaribous.size();i++)
			{
				DeadCaribous.get(i).die();
			}
			for(int i=0;i<DeadMooses.size();i++)
			{
				DeadMooses.get(i).die();
			}
			
			//on augmente l'�ge des herbivores et on fait mourir les vieux
			for(int i=0;i<PPContextCreator.allCaribous.size();i++)
			{
				PPContextCreator.allCaribous.get(i).age++;
				if(PPContextCreator.allCaribous.get(i).age>=15)
				{
					PPContextCreator.allCaribous.get(i).die();
				}					
			}
			for(int i=0;i<PPContextCreator.allMooses.size();i++)
			{
				PPContextCreator.allMooses.get(i).age++;
				if(PPContextCreator.allMooses.get(i).age>=20)
				{
					PPContextCreator.allMooses.get(i).die();
				}					
			}*/
			
			if ((nb_years)>1 && (nb_years)%5==0) // Initialement casté en double, mais inutile  ----- kl   
			{
				//Reloader les cartes, a chaque 5 ans
				
				carte = CST.Path_ressource_maps + "simu"+ Integer.toString(2000+nb_years)+".txt";
				
				System.out.println("nb_years: " + nb_years + ", donc chargement de: "+ carte );
				
		//RAISON DE MODIFICATION de "double.tostring" par "integer.toString(...)"	 ----   kl	
//				nb_years dans le else:44
//				nb_years dans le else après nb_years++:45
//				java.io.FileNotFoundException: ../ressources/sans_coupe/simu2045.0.txt (No such file or directory)
//				24554.0 , on est dans debut de new_year: 24554.0
				
				GIS.setup2(carte);
				
				//r�initialiser la position si dans une coupe (on tire 8 rayons, et quand on sort de la coupe pour un des rayons, on relocalise)
				for(int i=0;i<PPContextCreator.allCaribous.size();i++)
				{
					NdPoint pointC = space.getLocation(PPContextCreator.allCaribous.get(i));
					if (GIS.landUseMap.matrix[(int)pointC.getX()][(int)pointC.getY()]==13 || GIS.landUseMap.matrix[(int)pointC.getX()][(int)pointC.getY()]==14)
					{
						int temp=0;
						int dist=1;
						int[] count_no_cut={0,0,0,0,0,0,0,0};
						int[] xdir={1,1,0,-1,-1,-1,0,1};
						int[] ydir={0,1,1,1,0,-1,-1,-1};
						while (temp==0)
						{
							for (int j=0;j<8;j++)
							{
								if((int)pointC.getX()+(int)(dist*xdir[j])>=0 && (int)pointC.getX()+(int)(dist*xdir[j])<GIS.landUseMap.getSizeX() && (int)pointC.getY()+(int)(dist*ydir[j])>=0 && (int)pointC.getY()+(int)(dist*ydir[j])<GIS.landUseMap.getSizeY())
								{ //verifie qu'on ne sort pas de la carte
									if (GIS.landUseMap.matrix[(int)pointC.getX()+(int)(dist*xdir[j])][(int)pointC.getY()+(int)(dist*ydir[j])]!=13 && GIS.landUseMap.matrix[(int)pointC.getX()+(int)(dist*xdir[j])][(int)pointC.getY()+(int)(dist*ydir[j])]!=14)
									{	//dans un coupe (recente ou en r�g�n�ration) ?
										count_no_cut[j]++;
										if (count_no_cut[j]>=10)
										{ //v�rifie qu'on est vraiment sorti de la coupe (250m)
											space.moveByDisplacement(PPContextCreator.allCaribous.get(i),dist*xdir[j],dist*ydir[j],0); //relocalise
											temp=1;
										}
									}
									else
									{
										count_no_cut[j]=0;	//r�initialise si on retombe dans une coupe
									}
								}
							}
							dist++;
						}
					}
				}
			}  
			
			
//			//generer des nouveaux animaux (nb*2-predation infantile)
//			for(int i=0;i<PPContextCreator.allCaribous.size();i++)
//			{
//				if(Math.random()<0.15)  // a jouer avec taux de recrutement
//				{ //Courtois et al. 2001 
//					NdPoint pointC = space.getLocation(PPContextCreator.allCaribous.get(i));
//					Caribou caribou = new Caribou();     // create a new caribou
//					caribou.age=0;
//					context.add(caribou);
//					double x_localisation = pointC.getX();
//					double y_localisation = pointC.getY();
//					space.moveTo(caribou,x_localisation,y_localisation);
//					patch.moveTo(caribou,(int)x_localisation,(int)y_localisation);
//					patchDisplay.moveTo(caribou,Math.min((int)x_localisation/CST.div_affich,(int)GIS.landUseMap.width/CST.div_affich-1),Math.min((int)y_localisation/CST.div_affich,(int)GIS.landUseMap.height/CST.div_affich-1));
//					
//					caribou.xreal = x_localisation*25+GIS.landUseMap.getOriginX();
//					caribou.yreal = y_localisation*25+GIS.landUseMap.getOriginY();
//				}
//			}
//			for(int i=0;i<PPContextCreator.allMooses.size();i++)
//			{
//				if(Math.random()<0.45) // a jouer avec taux de recrutement
//				{ //Saether & Andersen 1996 -> 1.25(fecundity)*0.9(survival rate)/2(females) 
//					NdPoint pointM = space.getLocation(PPContextCreator.allMooses.get(i));
//					Moose moose= new Moose();     // create a new moose
//					moose.age=0;
//					context.add(moose);
//					double x_localisation = pointM.getX();
//					double y_localisation = pointM.getY();
//					space.moveTo(moose,x_localisation,y_localisation);
//					patch.moveTo(moose,(int)x_localisation,(int)y_localisation);
//					patchDisplay.moveTo(moose,Math.min((int)x_localisation/CST.div_affich,(int)GIS.landUseMap.width/CST.div_affich-1),Math.min((int)y_localisation/CST.div_affich,(int)GIS.landUseMap.height/CST.div_affich-1));
//					
//					moose.xreal = x_localisation*25+GIS.landUseMap.getOriginX();
//					moose.yreal = y_localisation*25+GIS.landUseMap.getOriginY();
//				}
//			}
			
			
			//ajout pour maintenir la population constante
			Parameters p = RunEnvironment.getInstance().getParameters();
			int nb_car_ajoute=(Integer)p.getValue("initialnumberofcaribou")-PPContextCreator.allCaribous.size();
			int nb_ori_ajoute=(Integer)p.getValue("initialnumberofmoose")-PPContextCreator.allMooses.size();
			
			for(int i=0;i<nb_car_ajoute;i++){
				
					Caribou caribou = new Caribou();     // create a new caribou
					context.add(caribou);                 // add a new caribou to the root context
					
					//System.out.println(caribou.getName()+"count : "+caribou.count);
					
					//double x_localisation = (CST.X_caribou_init[i]-GIS.landUseMap.getOriginX())/(25);
					//double y_localisation = (CST.Y_caribou_init[i]-GIS.landUseMap.getOriginY())/(25);
					double x_localisation = Math.random()*GIS.landUseMap.width;
					double y_localisation = Math.random()*GIS.landUseMap.height;
					
					while(GIS.landUseMap.matrix[(int)x_localisation][(int)y_localisation]!=(byte)11)
					{
						x_localisation = Math.random()*GIS.landUseMap.width;
						y_localisation = Math.random()*GIS.landUseMap.height;
					}

					space.moveTo(caribou,x_localisation,y_localisation);
					patch.moveTo(caribou,(int)x_localisation,(int)y_localisation);
					patchDisplay.moveTo(caribou,Math.min((int)x_localisation/CST.div_affich,(int)GIS.landUseMap.width/CST.div_affich-1),Math.min((int)y_localisation/CST.div_affich,(int)GIS.landUseMap.height/CST.div_affich-1));
					
					caribou.xreal = x_localisation*25+GIS.landUseMap.getOriginX();
					caribou.yreal = y_localisation*25+GIS.landUseMap.getOriginY();
				
				}
			
			for(int i=0;i<nb_ori_ajoute;i++)
			{
				
				Moose moose = new Moose();     // create a new moose
				context.add(moose);  
				
				//System.out.println(moose.getName()+"count : "+moose.count);
				
				//double x_localisation = (CST.X_orignal_init[i]-GIS.landUseMap.getOriginX())/(25);
				//double y_localisation = (CST.Y_orignal_init[i]-GIS.landUseMap.getOriginY())/(25);
				double x_localisation = Math.random()*GIS.landUseMap.width;
				double y_localisation = Math.random()*GIS.landUseMap.height;
				
				while(!(GIS.landUseMap.matrix[(int)x_localisation][(int)y_localisation]==(byte)12 || GIS.landUseMap.matrix[(int)x_localisation][(int)y_localisation]==(byte)71 || GIS.landUseMap.matrix[(int)x_localisation][(int)y_localisation]==(byte)72)){
					x_localisation = Math.random()*GIS.landUseMap.width;
					y_localisation = Math.random()*GIS.landUseMap.height;
				}
				
				space.moveTo(moose,x_localisation,y_localisation);
				patch.moveTo(moose,(int)x_localisation,(int)y_localisation);
				patchDisplay.moveTo(moose,Math.min((int)x_localisation/CST.div_affich,(int)GIS.landUseMap.width/CST.div_affich-1),Math.min((int)y_localisation/CST.div_affich,(int)GIS.landUseMap.height/CST.div_affich-1));
				
				moose.xreal = x_localisation*25+GIS.landUseMap.getOriginX();
				moose.yreal = y_localisation*25+GIS.landUseMap.getOriginY();							
			
			}
			
			
			//save_num_indiv();
			nb_dead_car=0;
			nb_dead_ori=0;
			
		
		}

} // fin de new_year()		
	
	
	
	//update the state of the resources -- only once, and at the beginning of each week
	@ScheduledMethod(start = 1, interval = 1, priority=2, pick=1)
	public void updateMaps() {
		int xdim = GIS.landUseMap.getSizeX();   // The x dimension of the physical space
		int ydim = GIS.landUseMap.getSizeY();   // The y dimension of the physical space
		//int xdim = ressources.lichenMap.getSizeX();   // The x dimension of the physical space
		//int ydim = ressources.lichenMap.getSizeY();   // The y dimension of the physical space		
		
		ISchedule s = RunEnvironment.getInstance().getCurrentSchedule();
		
		System.out.print(s.getTickCount()+" , ");
		if (s.getTickCount()%500==0)
			System.out.println();
		
		/*if (nbLDie==nbL){
			RunEnvironment.getInstance().endRun();
			System.out.println("");
			System.out.println("Arr�t� au nombre de loups");
		}*/
		
		//update des ressources � chaque dix jours
		/*if(s.getTickCount() % CST.step_ressources == 0){
			for(int x=1;x<xdim;x++){
				for(int y=1;y<ydim;y++){
					//lichen
					if(ressources.lichenMap.matrix[x][y]<GIS.lichenMap.matrix[x][y]){
						//ressources.lichenMap.matrix[x][y]=(short)(ressources.lichenMap.matrix[x][y]+CST.S_lichen*ressources.lichenMap.matrix[x][y]*(1-ressources.lichenMap.matrix[x][y]/GIS.lichenMap.matrix[x][y]));
						if(GIS.lichenMap.matrix[x][y]==0){
							System.out.println("food orignal : "+ressources.moosefoodMap.matrix[x][y]);
							System.out.println("");
						}
						//ressources.lichenMap.matrix[x][y]=(short)(ressources.lichenMap.matrix[x][y]+CST.S_lichen*ressources.lichenMap.matrix[x][y]*(1-ressources.lichenMap.matrix[x][y]/GIS.lichenMap.matrix[x][y]));
						ressources.lichenMap.matrix[x][y]=(int)(ressources.lichenMap.matrix[x][y]+CST.S_lichen*ressources.lichenMap.matrix[x][y]*(1-ressources.lichenMap.matrix[x][y]/GIS.lichenMap.matrix[x][y]));
					}
					if(ressources.moosefoodMap.matrix[x][y]<GIS.moosefoodMap.matrix[x][y]){
						//ressources.lichenMap.matrix[x][y]=(short)(ressources.lichenMap.matrix[x][y]+CST.S_lichen*ressources.lichenMap.matrix[x][y]*(1-ressources.lichenMap.matrix[x][y]/GIS.lichenMap.matrix[x][y]));
						if(GIS.moosefoodMap.matrix[x][y]==0){
							System.out.println("food orignal : "+ressources.moosefoodMap.matrix[x][y]);
							System.out.println("");
						}
						ressources.moosefoodMap.matrix[x][y]=(short)(ressources.moosefoodMap.matrix[x][y]+CST.S_moosefood*ressources.moosefoodMap.matrix[x][y]*(1-ressources.moosefoodMap.matrix[x][y]/GIS.moosefoodMap.matrix[x][y]));
					}
				}
			}
		}*/
		
		/*//update des marques odorif�res � chaque jour
		if(s.getTickCount() % CST.daily_ticks == 0){
			for(int x=1;x<xdim;x++){
				for(int y=1;y<ydim;y++){
					//lichen
					if(Scent_maps.scentWolf.matrix[x][y]>0){
						Scent_maps.scentWolf.matrix[x][y]--;
						if (Scent_maps.scentWolf.matrix[x][y]==0)
							Scent_maps.scentWolfID.matrix[x][y]=0;
					}
					/*if(Scent_maps.scentCaribou.matrix[x][y]>0)
						Scent_maps.scentCaribou.matrix[x][y]--;
					if(Scent_maps.scentMoose.matrix[x][y]>0)
						Scent_maps.scentMoose.matrix[x][y]--;
				}
			}
		}*/
		//update des marques odorif�res � chaque tick
		for(int x=1;x<xdim;x++){
			for(int y=1;y<ydim;y++){
				//lichen
				if(Scent_maps.scentWolf.matrix[x][y]>0){
					Scent_maps.scentWolf.matrix[x][y]=(short)(Scent_maps.scentWolf.matrix[x][y]+CST.TimeStep);
				}
				/*if(Scent_maps.scentCaribou.matrix[x][y]>0){
					Scent_maps.scentCaribou.matrix[x][y]=(short)(Scent_maps.scentCaribou.matrix[x][y]+CST.TimeStep);
				}
				if(Scent_maps.scentMoose.matrix[x][y]>0){
					Scent_maps.scentMoose.matrix[x][y]=(short)(Scent_maps.scentMoose.matrix[x][y]+CST.TimeStep);
				}*/
			}
		}
		
		
		//affichage du lichen
		//xdim = Math.min(GIS.landUseMap.getSizeX(),GIS.altitudeMap.getSizeX());   // The x dimension of the physical space
		//ydim = Math.min(GIS.landUseMap.getSizeY(),GIS.altitudeMap.getSizeY());   // The y dimension of the physical space
		/*for(int x=1;x<xdim/CST.div_affich;x++){
			for(int y=1;y<ydim/CST.div_affich;y++){
				//if (GIS.landUseMap.matrix[x][y] == 5 || GIS.landUseMap.matrix[x][y] == 7){
					//short temp =(short)Math.round(10*Math.random());
				map_affich.lichen_affich.matrix[x][y]=0;
					for (int xx=0;xx<CST.div_affich;xx++){
						for (int yy=0;yy<CST.div_affich;yy++){
							//map_affich.lichen_affich.matrix[x][y]=(short) (map_affich.lichen_affich.matrix[x][y]+lichenRaster.lichen.matrix[x*CST.div_affich-xx][y*CST.div_affich-yy]);
							map_affich.lichen_affich.matrix[x][y]=(byte) (map_affich.lichen_affich.matrix[x][y]+lichenRaster.lichen.matrix[x*CST.div_affich-xx][y*CST.div_affich-yy]);
						}
					}
				//}
					//map_affich.lichen_affich.matrix[x][y]=(short)(map_affich.lichen_affich.matrix[x][y]/CST.div_affich);
					map_affich.lichen_affich.matrix[x][y]=(byte)(map_affich.lichen_affich.matrix[x][y]/CST.div_affich);
			}
		}*/
				
	}
	
	
	/*@ScheduledMethod(start = 1, interval = 1, priority=2, pick=1)
	public void decrease_scent(){
		int xdim = GIS.scentMap.getSizeX();   // The x dimension of the physical space
		int ydim = GIS.scentMap.getSizeY();
		for(int x=1;x<xdim;x++){
			for(int y=1;y<ydim;y++){
				GIS.scentMap.matrix[x][y]=(byte)Math.max(0,GIS.scentMap.matrix[x][y]-1);
			}
		}
	}*/
	
	
	
	// Shedule the step method for agents.  The method is scheduled starting at
	// tick one with an interval of 1 tick.  Specifically, the step starts at 1, and
	// and recurs at 2,3,4,...etc
	/*@ScheduledMethod(start = 1, interval = 1, priority = 4)
	public void step_general() {
		ISchedule s = RunEnvironment.getInstance().getCurrentSchedule();
		
		step();
		}
		
	}*/
	
	@ScheduledMethod(start = 2, interval = 1, pick = 1, priority = 3)
	public void iterate(){
		if (hour==20){
			iteration_gen++;
			hour = 0;
		}
		else
			hour=hour+4;
	}
	
	
	
	@ScheduledMethod(start = 1, interval = 1, priority = 4)
	public void step() {
		// Override by subclasses
	}
	
   
	// Kill the agent
	@SuppressWarnings("unchecked")
	public void die(){
                // Get the context in which the agent resides.
		ISchedule s = RunEnvironment.getInstance().getCurrentSchedule();
		System.out.println();
		System.out.println("die "+this.getName()+" -- tick : "+s.getTickCount());
		Context context = ContextUtils.getContext(this);

		if (this.isCaribou()==1){
			PPContextCreator.allCaribous.remove(this);
			nb_dead_car++;
		}
		else if (this.isMoose()==1){
			PPContextCreator.allMooses.remove(this);
			nb_dead_ori++;
		}
		else
			PPContextCreator.allWolves.remove(this);
		
        // Remove the agent from the context if the context is not empty
		if (context.size() > 1)
			context.remove(this);
               // Otherwise if the context is empty, end the simulation
		else
			RunEnvironment.getInstance().endRun();
	}


	public int isCaribou() {
		return 0;
	}
	
	public int isMoose() {
		return 0;
	}

	public int isWolf() {
		return 0;
	}


	//Check potential destinations
	public void checkDestination(int i){
		// Override by subclasses
		
		
	}


	

	public void setHeading(double heading) {
		this.heading = heading;
	}


	public double getHeading() {
		return heading;
	}
	
	public void setTA(double TA) {
		this.TA = TA;
	}

	public double getTA() {
		return TA;
	}

	public void setName(String name){
		this.name=name;
	}
	
	public String getName(){
		return name;
	}
		
	public void setLocalisations(String[][] localisation){
		this.localisation=localisation;
	}
	
	public String[][] getLocalisation(){
		return localisation;
	}
	
	public void setID(int ID){
		this.ID = ID;
	}


	public int getID(){
		return ID;
	}
	
	public void setIteration(int iteration){
		this.iteration = iteration;
	}
	
			
	
	public void ScentMark(int Ax,int Ay,int Bx,int By){
		int x=Ax;
		int y=Ay;
		
		while(x!=Bx && y!=By){
			int dx = Bx-x;
			int dy = By-y;
			
			if(Math.abs(By-Ay)==0 || Math.abs(dy)==0){
				if (dx>0)
					x++;
				else
					x--;
			}
			else if (dx==0){
				if (dy>0)
					y++;
				else
					y--;
			}
			else if (dy==0){
				if (dx>0)
					x++;
				else
					x--;
			}
			else if (dx>0 && (double)Math.abs(dx)/(double)Math.abs(dy)>=(double)Math.abs(Bx-Ax)/(double)Math.abs(By-Ay)){
				x++;
			}
			else if (dy>0 && (double)Math.abs(dx)/(double)Math.abs(dy)<(double)Math.abs(Bx-Ax)/(double)Math.abs(By-Ay)){
				y++;
			}
			else if (dx<0 && (double)Math.abs(dx)/(double)Math.abs(dy)>=(double)Math.abs(Bx-Ax)/(double)Math.abs(By-Ay)){
				x--;
			}
			else if (dy<0 && (double)Math.abs(dx)/(double)Math.abs(dy)<(double)Math.abs(Bx-Ax)/(double)Math.abs(By-Ay)) {
				y--;
			}
			else
				System.out.println("Probleme rayon scentMark");
			
			if(this.isWolf()==1){
				/*if(Scent_maps.scentWolfID.matrix[x][y]==(short)((Wolf)this).pack)
					//Scent_maps.scentWolf.matrix[x][y]=(short)Math.min(15,Scent_maps.scentWolf.matrix[x][y]+10);
					Scent_maps.scentWolf.matrix[x][y]=(short)Math.min(60,Scent_maps.scentWolf.matrix[x][y]+60);
				else
					Scent_maps.scentWolf.matrix[x][y]=Scent_maps.scentWolf.matrix[x][y];*/
				Scent_maps.scentWolf.matrix[x][y]=1;
				Scent_maps.scentWolfID.matrix[x][y]=(short)((Wolf)this).pack;
			}
			/*else if(this.isCaribou()==1){
				Scent_maps.scentCaribou.matrix[x][y]=(short)Math.min(15,Scent_maps.scentCaribou.matrix[x][y]+10);
			}
			else{
				Scent_maps.scentMoose.matrix[x][y]=(short)Math.min(15,Scent_maps.scentMoose.matrix[x][y]+10);
			}*/
			
			/*else if(this.isCaribou()==1){
				Scent_maps.scentCaribou.matrix[x][y]=1;
			}
			else{
				Scent_maps.scentMoose.matrix[x][y]=1;
			}*/
		}
		
	}
	
	
	
	public double get_xreal(){
		return this.xreal;
	}
	
	public double get_yreal(){
		return this.yreal;
	}
	
	public short get_landsat(){
		Context context = ContextUtils.getContext(this);
		Grid patch = (Grid) context.getProjection("Simple Grid");
		GridPoint pointG = patch.getLocation(this);
		int Ax = pointG.getX();   // The x-ccordinate of the caribou's current patch
		int Ay = pointG.getY();
		return GIS.landUseMap.matrix[Ax][Ay];
	}
	
	
	public void save_num_indiv(){
		try{
BufferedWriter out = new BufferedWriter(new FileWriter("../predateur_proies_full_simu/output/save_num_car"+"_"+CST.pp.getValueAsString("numero")+".txt",true));  // Modifier le nom du path
							
							
							out.write(String.valueOf(PPContextCreator.allCaribous.size()));
							out.newLine();
							out.close();
							
BufferedWriter out2 = new BufferedWriter(new FileWriter("../predateur_proies_full_simu/output/save_num_ori"+"_"+CST.pp.getValueAsString("numero")+".txt",true));  // Modifier le nom du path
							
							
							out2.write(String.valueOf(PPContextCreator.allMooses.size()));
							out2.newLine();
							out2.close();
							
BufferedWriter out3 = new BufferedWriter(new FileWriter("../predateur_proies_full_simu/output/save_num_loup"+"_"+CST.pp.getValueAsString("numero")+".txt",true));  // Modifier le nom du path
							
							
							out3.write(String.valueOf(PPContextCreator.allWolves.size()));
							out3.newLine();
							out3.close();
		}
		catch (IOException e){
		    e.printStackTrace();
		}
	}
	
	public void save_numdeadpred(){
		try{
			

			System.out.println("-----Dans save_numdeadpred---- ");
			BufferedWriter out = new BufferedWriter(new FileWriter("../predateur_proies_full_simu/output/save_num_dead_car"+"_"+CST.pp.getValueAsString("numero")+".txt",true));  // Modifier le nom du path
			System.out.println("-----nb_dead_car_pred: " + nb_dead_car_pred);
			out.write(Agent.nb_years + " " + String.valueOf(Agent.nb_dead_car_pred));
			out.newLine();
			out.close();


			BufferedWriter out2 = new BufferedWriter(new FileWriter("../predateur_proies_full_simu/output/save_num_dead_ori"+"_"+CST.pp.getValueAsString("numero")+".txt",true));  // Modifier le nom du path
			out2.write(Agent.nb_years + " " + String.valueOf(Agent.nb_dead_ori_pred));
			out2.newLine();
			out2.close();
		}
		catch (IOException e){
			e.printStackTrace();
		}
	}
}



